package com.boshanam.model.vos.domain.user;

import java.util.Date;

import org.springframework.security.GrantedAuthority;
import org.springframework.util.Assert;

/**
 * 
 * @author Sivakumar Y User.java Dec 12, 2009 11:47:04 PM www.ibigbang.net
 * 
 */
public class UserVO extends UserVOImmutable {

	private static final long serialVersionUID = 1L;

	// ~ Instance fields ======================================================
	// All Instance fields are inherited from UserAttribute, Please add fields
	// to UserAttribute class if any needed.

	// ~ Constructors
	// =============================================================

	/**
	 * 
	 * Construct the <code>User</code> with the details required by
	 * {@link org.acegisecurity.providers.dao.DaoAuthenticationProvider}.
	 * 
	 * @param firstName
	 * @param lastName
	 * @param middleName
	 * @param phoneNumber 
	 * @param username
	 *            the username presented to the
	 *            <code>DaoAuthenticationProvider</code>
	 * @param password
	 *            the password that should be presented to the
	 *            <code>DaoAuthenticationProvider</code>
	 * @param enabled
	 *            set to <code>true</code> if the user is enabled
	 * @param accountNonExpired
	 *            set to <code>true</code> if the account has not expired
	 * @param credentialsNonExpired
	 *            set to <code>true</code> if the credentials have not expired
	 * @param accountNonLocked
	 *            set to <code>true</code> if the account is not locked
	 * @param authorities
	 *            the authorities that should be granted to the caller if they
	 *            presented the correct username and password and the user is
	 *            enabled
	 * 
	 * @throws IllegalArgumentException
	 *             if a <code>null</code> value was passed either as a parameter
	 *             or as an element in the <code>GrantedAuthority[]</code> array
	 */
	public UserVO(String id, String firstName, String lastName,
			String middleName, String phoneNumber, Date birthDate, String username, String password, String email,
			UserSettingsVO userSettings, boolean enabled, boolean verified,
			boolean accountNonExpired, boolean credentialsNonExpired,
			boolean accountNonLocked, GrantedAuthority[] authorities, String signinHistory, String description)
			throws IllegalArgumentException {

		if (((username == null) || "".equals(username)) || (password == null)
				|| (email == null) || "".equals(email)) {
			throw new IllegalArgumentException(
					"Cannot pass null or empty values to constructor");
		}

		this.ID = id;
		this.firstName = firstName;
		this.lastName = lastName;
		this.middleName = middleName;
		this.phoneNumber = phoneNumber;
		this.birthDate = birthDate;
		this.username = username;
		this.password = password;
		this.email = email;
		this.userSettings = userSettings;
		this.enabled = enabled;
		this.verified = verified;
		this.accountNonExpired = accountNonExpired;
		this.credentialsNonExpired = credentialsNonExpired;
		this.accountNonLocked = accountNonLocked;
		if (authorities != null && authorities.length < 1) {
			setAuthorities(authorities);
		} else {
			setAuthorities(new GrantedAuthority[] { new GrantedAuthorityImplVO(
					"ANONYMUS_USER") });
		}
		this.signinHistory = signinHistory;
		this.description = description;
	}

	// ~ Methods
	// ====================================================================

	/**
	 * Default Constructor
	 */
	public UserVO() {
		super();
	}

	/**
	 * This constructor is used by UserRegForm to provide
	 * UserSetting object to the accessors and to avoid 
	 * NullPointerException.
	 * @param userSettingsVO
	 */
	public UserVO(UserSettingsVO userSettingsVO) {
		super();
		this.userSettings = userSettingsVO;
	}

	public boolean equals(Object rhs) {
		if (!(rhs instanceof UserVO) || (rhs == null)) {
			return false;
		}

		UserVO userVOImmutable = (UserVO) rhs;

		// We rely on constructor to guarantee any User has non-null and >0
		// authorities
		if (userVOImmutable.getAuthorities().length != this.getAuthorities().length) {
			return false;
		}

		for (int i = 0; i < this.getAuthorities().length; i++) {
			if (!this.getAuthorities()[i].equals(userVOImmutable
					.getAuthorities()[i])) {
				return false;
			}
		}

		// We rely on constructor to guarantee non-null username and password
		return (this.getPassword().equals(userVOImmutable.getPassword())
				&& this.getUsername().equals(userVOImmutable.getUsername())
				&& (this.isAccountNonExpired() == userVOImmutable
						.isAccountNonExpired())
				&& (this.isAccountNonLocked() == userVOImmutable
						.isAccountNonLocked())
				&& (this.isCredentialsNonExpired() == userVOImmutable
						.isCredentialsNonExpired()) && (this.isEnabled() == userVOImmutable
				.isEnabled()));
	}

	public void setAuthorities(GrantedAuthority[] authorities) {
		Assert.notNull(authorities,
						"Cannot pass a null GrantedAuthority array");

		for (int i = 0; i < authorities.length; i++) {
			Assert.notNull(
							authorities[i],
							"Granted authority element "
									+ i
									+ " is null - GrantedAuthority[] cannot contain any null elements");
		}

		this.authorities = authorities;
	}

	public void setUserSettings(UserSettingsVO userSettings) {
		this.userSettings = userSettings;
	}

	public void setID(String id) {
		ID = id;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public void setAccountNonExpired(boolean accountNonExpired) {
		this.accountNonExpired = accountNonExpired;
	}

	public void setAccountNonLocked(boolean accountNonLocked) {
		this.accountNonLocked = accountNonLocked;
	}

	public void setCredentialsNonExpired(boolean credentialsNonExpired) {
		this.credentialsNonExpired = credentialsNonExpired;
	}

	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
	}

	public void setDescription(String description) {
		this.description = description;
	}

}
